package com.education.quartz.manage;

import com.education.quartz.pojo.ScheduleInfoDto;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @Author: liftsail
 * @Date: 2022/11/22 16:09
 * @Description: 不积跬步无以至千里
 */
@Slf4j
@Component
public class ScheduleManage {

    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;

    /**
     * 添加定时任务Job
     */
    @SneakyThrows
    public String addSchedule(Integer courseId, ScheduleInfoDto dto) {
        String userSuf = "_" + courseId;
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("courseId", courseId);
        //任务信息
        JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(dto.getJobClassName()))
                .withIdentity(dto.getJobName(), dto.getJobGroup() + userSuf)
                .withDescription(dto.getDescName())
                .storeDurably()
                .build();
        //Cron表达式
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(dto.getCronExpression());
        //触发器信息
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(dto.getTriggerName(), dto.getTriggerGroup() + userSuf)
                .forJob(dto.getJobName(), dto.getJobGroup() + userSuf)
                .startNow()
                .usingJobData(jobDataMap)
                .withSchedule(cronScheduleBuilder)
                .withDescription(dto.getTriggerDescription())
                .build();
        //如果任务名、组存在，则在任务上添加触发器
        Date date = null;
        //JobKey jobKey1 = JobKey.jobKey(dto.getJobName(), dto.getJobGroup() + userSuf);
        JobKey jobKey = new JobKey(dto.getJobName(), dto.getJobGroup() + userSuf);
        if (scheduler.checkExists(jobKey)) {
            date = scheduler.scheduleJob(cronTrigger);
        } else {
            //如果任务不存在，添加任务和触发器
            date = scheduler.scheduleJob(jobDetail, cronTrigger);
        }
        if (date == null) {
            return "任务添加失败";
        }
        log.info("任务添加成功,任务信息：{}", dto);
        return "任务添加成功";
    }

    /**
     * 删除定时任务
     *
     * @param triggerName
     * @param triggerGroup
     * @param courseId
     */
    @SneakyThrows
    public void deleteSchedule(String triggerName, String triggerGroup, Integer courseId, String jobName, String jobGroup) {
        try {
            TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroup + "_" + courseId);
            //删除触发器之前暂停触发器
            scheduler.pauseTrigger(triggerKey);
            //删除触发器
            boolean res = scheduler.unscheduleJob(triggerKey);
            //如果触发器删除失败
            log.info("定时任务删除结果 {}", res);
            if (!res) {
                return;
            }

            //log.info("触发器名：{}，触发器组：{} ，删除成功", triggerName, triggerGroup);
            //如果任务下没有触发器，删除任务
            JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
            List<? extends Trigger> triggersOfJob = scheduler.getTriggersOfJob(jobKey);
            if (triggersOfJob.size() == 0) {
                scheduler.pauseJob(jobKey);
                boolean r = scheduler.deleteJob(jobKey);
                //log.info("任务名：{}，任务组：{} ，删除结果 {}", jobName, jobGroup, r);
            }
        } catch (SchedulerException e) {
            //log.error("任务名：{}，任务组：{}，删除异常,{}", triggerName, triggerGroup, e);
        }
    }

    /**
     * 删除定时任务
     *
     * @param jobKey
     * @param triggerKey
     */
    @SneakyThrows
    public void deleteSchedule(JobKey jobKey, TriggerKey triggerKey) {
        try {
            //删除触发器之前暂停触发器
            scheduler.pauseTrigger(triggerKey);
            //删除触发器
            boolean res = scheduler.unscheduleJob(triggerKey);
            //如果触发器删除失败
            log.info("定时任务删除结果 {}", res);
            if (!res) {
                return;
            }

            log.info("触发器名：{}，触发器组：{} ，删除成功", triggerKey.getName(), triggerKey.getGroup());
            //如果任务下没有触发器，删除任务
            List<? extends Trigger> triggersOfJob = scheduler.getTriggersOfJob(jobKey);
            if (triggersOfJob.size() == 0) {
                scheduler.pauseJob(jobKey);
                boolean r = scheduler.deleteJob(jobKey);
                log.info("任务名：{}，任务组：{} ，删除结果 {}", jobKey.getName(), jobKey.getGroup(), r);
            }
        } catch (SchedulerException e) {
            log.error("任务名：{}，任务组：{}，删除异常,{}", triggerKey.getName(), triggerKey.getGroup(), e);
        }
    }

}
